package com.riccardocardin.structured.concurrency.client;

import com.riccardocardin.structured.concurrency.model.Model.UserId;
import com.riccardocardin.structured.concurrency.service.RepositoryService;
import com.riccardocardin.structured.concurrency.service.RepositoryServiceImpl;
import com.riccardocardin.structured.concurrency.util.Concurrents;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutionException;

public class CannotShutDownDemo {

    private static final Logger LOGGER = LoggerFactory.getLogger("GitHubApp");

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        RepositoryService repositoryService = new RepositoryServiceImpl();
        // run forever
        /*var repositories = Concurrents.race(() -> repositoryService.findRepositories(new UserId(1L)),
                CannotShutDownDemo::mineBitcoin);*/
        // ok, shutdown normally
        var repositories = Concurrents.race(() -> repositoryService.findRepositories(new UserId(1L)),
                CannotShutDownDemo::mineBitcoinAwareInterrupt);
        LOGGER.info("GitHub user's repositories: {}", repositories);
    }

    record Bitcoin(String hash) {
    }

    static Bitcoin mineBitcoin() {
        LOGGER.info("Mining Bitcoin...");
        while (alwaysTrue()) {
            // Empty body
        }
        LOGGER.info("Bitcoin mined!");

        return new Bitcoin("bitcoin-hash");
    }

    static Bitcoin mineBitcoinAwareInterrupt() throws InterruptedException {
        LOGGER.info("Mining Bitcoin...");
        while (alwaysTrue()) {
            if (Thread.currentThread().isInterrupted()) {
                LOGGER.info("Mining Bitcoin interrupted!");
                throw new InterruptedException();
            }
        }
        LOGGER.info("Bitcoin mined!");

        return new Bitcoin("bitcoin-hash");
    }

    private static boolean alwaysTrue() {
        return true;
    }
}
